home *** CD-ROM | disk | FTP | other *** search
/ AM/FM: Amiga Musicians' Freeware Magazine 1 / AM-FM 1.adf / TechCorner / midiroutines.a < prev    next >
Text File  |  1991-10-03  |  5KB  |  245 lines

  1. ;    Routines for sending/receiving MIDI data to/from the serial port
  2. ;    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3. ;    Written by Teijo Kinnunen.
  4.  
  5. ;    For a complete description of these routines, see the
  6. ;    accompanying text file.
  7.  
  8. ;    Please feel free to use these routines in your own programs!!
  9.  
  10. ;    If you want to install the input handler, set INPUT to 1.
  11. INPUT    EQU    0
  12.  
  13. ;    These XDEFs allow you to link e.g. with C-programs.
  14.  
  15.     XDEF    _GetSerial
  16.     XDEF    _FreeSerial
  17.     XDEF    _AddMIDIData
  18.     XDEF    _ResetMIDI
  19.  
  20.     CODE    ;some assemblers require SECTION
  21.  
  22. _GetSerial:    move.l    a6,-(sp)
  23.         bsr.s    GetSer
  24.         tst.l    d0
  25.         beq.s    GSerial_exit
  26.         movea.l    4,a6
  27.         jsr    -$84(a6)    ;Forbid()
  28.         lea    $15e(a6),a0
  29.         lea    serdevname(pc),a1
  30.         jsr    -$114(a6)    ;FindName()
  31.         tst.l    d0
  32.         beq.s    GSerial_nosd
  33.         move.l    d0,a1
  34.         jsr    -$1b6(a6)    ;RemDevice()
  35. GSerial_nosd    jsr    -$8a(a6)    ;Permit()
  36.         bsr.s    GetSer
  37. GSerial_exit    move.l    (sp)+,a6
  38.         rts
  39.  
  40. GetSer:        move.l    a6,-(sp)
  41.         movea.l    4,a6
  42.         moveq    #0,d0
  43.         lea    miscresname(pc),a1
  44.         jsr    -$1f2(a6)
  45.         tst.l    d0
  46.         beq.s    GS_error
  47.         move.l    d0,miscresbase
  48.         move.l    d0,a6
  49.         moveq    #0,d0
  50.         lea    myname(pc),a1
  51.         jsr    -$6(a6)    ;AllocMiscResource()
  52.         tst.l    d0
  53.         bne.s    GS_error
  54.         st    serportalloc
  55. ;It's usually required to call _InitSerial only once, so it's
  56. ;convenient to do it now.
  57.         bsr.s    _InitSerial
  58.         moveq    #0,d0
  59. GS_exit        move.l    (sp)+,a6
  60.         rts
  61. GS_error    moveq    #-1,d0
  62.         bra.s    GS_exit
  63.  
  64. _InitSerial    move.l    a6,-(sp)
  65.         move.b    serportalloc(pc),d0
  66.         beq.s    InitSer_exit
  67.         move.w    #114,$dff032    ;$dff032 = SERPER
  68.         moveq    #0,d0
  69.         lea    tbeinterrupt(pc),a1
  70.         movea.l    4,a6
  71.         jsr    -$a2(a6)    ;SetIntVector()
  72.         move.l    d0,prevtbe
  73.     IFNE INPUT
  74.         moveq    #11,d0
  75.         lea    rbfinterrupt(pc),a1
  76.         jsr    -$a2(a6)    ;SetIntVector()
  77.         move.l    d0,prevrbf
  78.         move.w    #$8801,$dff09a
  79.     ELSEIF
  80.         move.w    #$8001,$dff09a
  81.     ENDC
  82. InitSer_exit    move.l    (sp)+,a6
  83.         rts
  84.  
  85. SerIntHandler:    move.w    #$4000,$9a(a0)    ;$dff09a = INTENA
  86.         addq.b    #1,$126(a6)    ;ExecBase->IDNestCnt
  87.         move.w    #1,$9c(a0)    ;$dff09c = INTREQ
  88.         move.b    bytesinbuff(pc),d0
  89.         beq.s    SerInt_bufempty
  90.         movea.l    4(a1),a5
  91.         move.w    #$100,d1
  92.         move.b    (a5)+,d1
  93.         move.w    d1,$30(a0)    ;$dff030 = SERDAT
  94.         cmpa.l    a1,a5
  95.         bne.s    SerInt_resrp
  96.         lea    sendbuffer(pc),a5
  97. SerInt_resrp    subq.b    #1,d0
  98.         move.b    d0,8(a1)
  99.         move.l    a5,4(a1)
  100. SerInt_exit    subq.b    #1,$126(a6)
  101.         bge.s    SerInt_X
  102.         move.w    #$c000,$9a(a0)
  103. SerInt_X    rts
  104. SerInt_bufempty    st    9(a1)
  105.         bra.s    SerInt_exit
  106.  
  107. _AddMIDIData:    move.b    serportalloc(pc),d1
  108.         beq.s    AMD_rts
  109.         movem.l    a2/a6,-(sp)
  110.         movea.l    4,a6
  111.         move.w    #$4000,$dff09a
  112.         addq.b    #1,$126(a6)
  113.         lea    buffptr(pc),a2
  114.         tst.b    9(a2)
  115.         beq.s    AMD_noTBEreq
  116.         clr.b    9(a2)
  117.         move.w    #$8001,$dff09c
  118. AMD_noTBEreq    movea.l    (a2),a1
  119. AMD_dataloop    move.b    (a0)+,d1
  120.         bpl.s    AMD_nostatus
  121.         cmp.b    #$ef,d1
  122.         bhi.s    AMD_nostatus
  123.         cmp.b    lastcmdbyte(pc),d1
  124.         beq.s    AMD_noinsbyte
  125.         move.b    d1,10(a2)
  126. AMD_nostatus    move.b    d1,(a1)+
  127.         addq.b    #1,8(a2)
  128. AMD_noinsbyte    cmpa.l    a2,a1
  129.         bne.s    AMD_noptrreset
  130.         lea    sendbuffer(pc),a1
  131. AMD_noptrreset    subq.b    #1,d0
  132.         bne.s    AMD_dataloop
  133.         move.l    a1,(a2)
  134.         subq.b    #1,$126(a6)
  135.         bge.s    AMD_x
  136.         move.w    #$c000,$dff09a
  137. AMD_x        movem.l    (sp)+,a2/a6
  138. AMD_rts        rts
  139.  
  140. _ResetMIDI:    move.l    a6,-(sp)
  141.         movea.l    4,a6
  142.         move.w    #$4000,$dff09a
  143.         addq.b    #1,$126(a6)
  144.         lea    buffptr(pc),a1
  145.         lea    sendbuffer(pc),a0
  146.         move.l    a0,(a1)+
  147.         move.l    a0,(a1)+
  148.         clr.b    (a1)+
  149.         addq.l    #1,a1
  150.         clr.b    (a1)
  151.         subq.b    #1,$126(a6)
  152.         bge.s    ResetM_x
  153.         move.w    #$c000,$dff09a
  154. ResetM_x    move.l    (sp)+,a6
  155.         rts
  156.  
  157.     IFNE INPUT
  158.         XREF    _maintsk    ;the task to be signalled
  159.         XREF    _sigmask    ;the signal mask
  160.         XREF    _inputbuff    ;a 3-byte input note buffer
  161.  
  162. RBFIntHandler:    move.w    $18(a0),d0    ;$dff018 = SERDATR
  163.         move.w    #$0800,$9c(a0)
  164.         tst.b    d0
  165.         bpl.s    RBF_nostatus
  166.         cmp.b    #$f7,d0
  167.         bhi.s    RBF_exit
  168.         move.b    d0,(a1)
  169.         clr.b    3(a1)
  170. RBF_exit    rts
  171. RBF_nostatus    moveq    #0,d1
  172.         move.b    3(a1),d1
  173.         move.b    d0,1(a1,d1.w)
  174.         addq.b    #1,d1
  175.         cmp.b    #2,d1
  176.         bge.s    RBF_signal
  177.         move.b    d1,3(a1)
  178.         rts
  179. RBF_signal    clr.b    3(a1)
  180.         move.b    (a1),d0
  181.         and.b    #$f0,d0
  182.         cmp.b    #$90,d0
  183.         beq.s    RBF_sig
  184.         cmp.b    #$80,d0
  185.         bne.s    RBF_nosig
  186. RBF_sig        lea    _inputbuff,a0
  187.         move.b    (a1)+,(a0)+
  188.         move.b    (a1)+,(a0)+
  189.         move.b    (a1),(a0)
  190.         movea.l    _maintsk,a1
  191.         move.l    _sigmask,d0
  192.         jsr    -$144(a6)    ;Signal()
  193. RBF_nosig    rts
  194.     ENDC
  195.  
  196. _FreeSerial:    move.l    a6,-(sp)
  197.         tst.b    serportalloc
  198.         beq.s    FreeSer_xit
  199.         move.w    #$0801,$dff09a
  200.         movea.l    4,a6
  201.         moveq    #0,d0
  202.         move.l    prevtbe(pc),a1
  203.         jsr    -$a2(a6)    ;SetIntVector()
  204.     IFNE INPUT
  205.         moveq    #11,d0
  206.         move.l    prevrbf(pc),a1
  207.         jsr    -$a2(a6)    ;SetIntVector()
  208.     ENDC
  209.         movea.l    miscresbase(pc),a6
  210.         moveq    #0,d0
  211.         jsr    -$c(a6)        ;FreeMiscResource()
  212.         clr.b    serportalloc
  213. FreeSer_xit    move.l    (sp)+,a6
  214.         rts
  215.  
  216. ;DON'T CHANGE THE ORDER OF THESE 6 ENTRIES
  217. sendbuffer    ds.b    128
  218. buffptr        dc.l    sendbuffer    ;buffer WRITE pointer
  219. readbuffptr    dc.l    sendbuffer    ;buffer READ pointer
  220. bytesinbuff    dc.b    0
  221. bufferempty    dc.b    -1
  222. lastcmdbyte    dc.b    0
  223.  
  224. miscresname    dc.b    'misc.resource',0
  225. serportalloc    dc.b    0
  226. ;USE THE NAME OF YOUR OWN PROGRAM INSTEAD OF 'MyProggie'
  227. myname        dc.b    'MyProggie',0
  228. tbename        dc.b    'MyProggie serial interrupt',0
  229. serdevname    dc.b    'serial.device',0
  230.         even
  231. miscresbase    dc.l    0
  232. prevtbe        dc.l    0
  233. tbeinterrupt    dc.w    0,0,0,0,0
  234.         dc.l    tbename,buffptr,SerIntHandler
  235.  
  236.     IFNE INPUT
  237. recmidi        dc.b    0,0,0,0
  238. prevrbf        dc.l    0
  239. rbfinterrupt    dc.w    0,0,0,0,0
  240.         dc.l    rbfname,recmidi,RBFIntHandler
  241. rbfname        dc.b    'MyProggie RBF-interrupt',0
  242.     ENDC
  243.  
  244.     END
  245.